/**
 * 重复分析页面专用组件
 * 提供重复内容检测、相似度分析和簇分析功能
 */
class DuplicateAnalysis extends BaseComponent {
    constructor(options = {}) {
        super({
            id: options.id || 'duplicateAnalysis',
            ...options
        });

        // API客户端
        this.apiClient = options.apiClient || window.apiClient;

        // 组件状态
        this.state = {
            data: null,
            loading: false,
            activeTab: 'similarity',
            filters: {
                task_id: null,
                start_date: null,
                end_date: null,
                min_similarity: 0.8,
                max_similarity: 1.0,
                cluster_size: 2
            }
        };

        // 图表实例
        this.charts = {
            similarityDistribution: null,
            clusterAnalysis: null,
            popularDuplicates: null,
            duplicateTrends: null
        };

        // 统计卡片实例
        this.statCards = {
            totalRecords: null,
            avgSimilarity: null,
            duplicateRate: null,
            potentialDuplicates: null
        };

        // 筛选面板实例
        this.filterPanel = null;

        // 标签页配置
        this.tabs = [
            { id: 'similarity', name: '相似度分布', icon: '📊' },
            { id: 'clusters', name: '重复簇', icon: '🔗' },
            { id: 'popular', name: '热门重复', icon: '🔥' },
            { id: 'trends', name: '重复趋势', icon: '📈' },
            { id: 'details', name: '重复详情', icon: '📋' }
        ];
    }

    /**
     * 渲染组件
     */
    render() {
        if (!this.container) return;

        this.container.innerHTML = `
            <!-- 页面标题 -->
            <div class="mb-8">
                <h1 class="text-3xl font-bold text-gray-800 mb-2">重复分析</h1>
                <p class="text-gray-600">识别和分析信访记录中的重复内容和相似模式</p>
            </div>

            <!-- 筛选面板 -->
            <div id="${this.id}_filterPanel" class="mb-8"></div>

            <!-- 统计概览 -->
            <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-8">
                <div id="${this.id}_totalRecords" class="stat-card-container"></div>
                <div id="${this.id}_avgSimilarity" class="stat-card-container"></div>
                <div id="${this.id}_duplicateRate" class="stat-card-container"></div>
                <div id="${this.id}_potentialDuplicates" class="stat-card-container"></div>
            </div>

            <!-- 标签页导航 -->
            <div class="bg-white rounded-lg shadow-md mb-6">
                <div class="border-b border-gray-200">
                    <nav class="flex space-x-8 px-6" aria-label="标签页">
                        ${this.tabs.map(tab => `
                            <button class="tab-button py-4 px-1 border-b-2 font-medium text-sm focus:outline-none transition-colors ${tab.id === 'similarity' ? 'border-blue-500 text-blue-600' : 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300'}"
                                    data-tab="${tab.id}">
                                <span class="mr-2">${tab.icon}</span>${tab.name}
                            </button>
                        `).join('')}
                    </nav>
                </div>
            </div>

            <!-- 标签页内容 -->
            <div class="tab-content">
                <!-- 相似度分布 -->
                <div class="tab-pane ${this.state.activeTab === 'similarity' ? 'active' : ''}" id="similarity-pane">
                    <div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
                        <div class="lg:col-span-2">
                            <div id="${this.id}_similarityChart" class="chart-container bg-white rounded-lg shadow-md p-6"></div>
                        </div>
                        <div class="lg:col-span-1">
                            <div class="bg-white rounded-lg shadow-md p-6">
                                <h3 class="text-lg font-semibold text-gray-800 mb-4">相似度统计</h3>
                                <div id="${this.id}_similarityStats" class="space-y-3"></div>
                            </div>
                        </div>
                    </div>
                </div>

                <!-- 重复簇 -->
                <div class="tab-pane ${this.state.activeTab === 'clusters' ? 'active' : ''}" id="clusters-pane">
                    <div class="grid grid-cols-1 lg:grid-cols-3 gap-6 mb-6">
                        <div class="lg:col-span-2">
                            <div id="${this.id}_clusterChart" class="chart-container bg-white rounded-lg shadow-md p-6"></div>
                        </div>
                        <div class="lg:col-span-1">
                            <div class="bg-white rounded-lg shadow-md p-6">
                                <h3 class="text-lg font-semibold text-gray-800 mb-4">簇统计</h3>
                                <div id="${this.id}_clusterStats" class="space-y-3"></div>
                            </div>
                        </div>
                    </div>
                    <div class="bg-white rounded-lg shadow-md p-6">
                        <h3 class="text-lg font-semibold text-gray-800 mb-4">簇可视化</h3>
                        <div id="${this.id}_clusterVisualization" class="space-y-4"></div>
                    </div>
                </div>

                <!-- 热门重复 -->
                <div class="tab-pane ${this.state.activeTab === 'popular' ? 'active' : ''}" id="popular-pane">
                    <div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
                        <div class="lg:col-span-2">
                            <div id="${this.id}_popularChart" class="chart-container bg-white rounded-lg shadow-md p-6"></div>
                        </div>
                        <div class="lg:col-span-1">
                            <div class="bg-white rounded-lg shadow-md p-6">
                                <h3 class="text-lg font-semibold text-gray-800 mb-4">热门重复排行</h3>
                                <div id="${this.id}_popularRanking" class="space-y-3"></div>
                            </div>
                        </div>
                    </div>
                </div>

                <!-- 重复趋势 -->
                <div class="tab-pane ${this.state.activeTab === 'trends' ? 'active' : ''}" id="trends-pane">
                    <div id="${this.id}_trendsChart" class="chart-container bg-white rounded-lg shadow-md p-6"></div>
                </div>

                <!-- 重复详情 -->
                <div class="tab-pane ${this.state.activeTab === 'details' ? 'active' : ''}" id="details-pane">
                    <div class="bg-white rounded-lg shadow-md p-6">
                        <h3 class="text-lg font-semibold text-gray-800 mb-4">重复详情</h3>
                        <div id="${this.id}_duplicateDetails" class="space-y-4"></div>
                    </div>
                </div>
            </div>

            <!-- 加载遮罩 -->
            <div id="${this.id}_loadingOverlay" class="loading-overlay fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 hidden">
                <div class="bg-white rounded-lg p-6 flex items-center space-x-3">
                    <div class="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-500"></div>
                    <span class="text-gray-700">正在分析数据...</span>
                </div>
            </div>
        `;

        this.initSubComponents();
        this.loadTasks();
        this.setDefaultDates();
    }

    /**
     * 初始化子组件
     */
    initSubComponents() {
        // 初始化筛选面板
        this.filterPanel = new FilterPanel({
            id: `${this.id}_filterPanel`,
            title: '分析筛选',
            filters: [
                {
                    name: 'task_id',
                    label: '分析任务',
                    type: 'select',
                    options: [{ value: '', label: '全部任务' }],
                    placeholder: '选择分析任务'
                },
                {
                    name: 'start_date',
                    label: '开始日期',
                    type: 'date',
                    placeholder: '选择开始日期'
                },
                {
                    name: 'end_date',
                    label: '结束日期',
                    type: 'date',
                    placeholder: '选择结束日期'
                },
                {
                    name: 'min_similarity',
                    label: '最小相似度',
                    type: 'number',
                    min: 0,
                    max: 1,
                    step: 0.1,
                    default: 0.8,
                    placeholder: '0.8'
                },
                {
                    name: 'max_similarity',
                    label: '最大相似度',
                    type: 'number',
                    min: 0,
                    max: 1,
                    step: 0.1,
                    placeholder: '1.0'
                },
                {
                    name: 'cluster_size',
                    label: '最小簇大小',
                    type: 'number',
                    min: 2,
                    step: 1,
                    placeholder: '2'
                }
            ],
            onFilter: (filters) => this.handleFilter(filters),
            collapsible: false
        });

        // 初始化统计卡片
        this.statCards.totalRecords = new StatCard({
            id: `${this.id}_totalRecords`,
            title: '总记录数',
            value: '-',
            icon: '📊',
            color: 'blue',
            trend: null
        });

        this.statCards.avgSimilarity = new StatCard({
            id: `${this.id}_avgSimilarity`,
            title: '平均相似度',
            value: '-',
            icon: '📈',
            color: 'green',
            trend: null
        });

        this.statCards.duplicateRate = new StatCard({
            id: `${this.id}_duplicateRate`,
            title: '重复率',
            value: '-',
            icon: '🔄',
            color: 'yellow',
            trend: null
        });

        this.statCards.potentialDuplicates = new StatCard({
            id: `${this.id}_potentialDuplicates`,
            title: '潜在重复',
            value: '-',
            icon: '⚠️',
            color: 'red',
            trend: null
        });

        // 初始化图表容器
        this.charts.similarityDistribution = new ChartContainer({
            id: `${this.id}_similarityChart`,
            title: '相似度分布',
            type: 'echarts',
            config: {
                responsive: true,
                maintainAspectRatio: false
            }
        });

        this.charts.clusterAnalysis = new ChartContainer({
            id: `${this.id}_clusterChart`,
            title: '重复簇大小分布',
            type: 'echarts',
            config: {
                responsive: true,
                maintainAspectRatio: false
            }
        });

        this.charts.popularDuplicates = new ChartContainer({
            id: `${this.id}_popularChart`,
            title: '热门重复内容',
            type: 'echarts',
            config: {
                responsive: true,
                maintainAspectRatio: false
            }
        });

        this.charts.duplicateTrends = new ChartContainer({
            id: `${this.id}_trendsChart`,
            title: '重复趋势',
            type: 'echarts',
            config: {
                responsive: true,
                maintainAspectRatio: false
            }
        });

        // 挂载子组件
        this.filterPanel.mount();
        Object.values(this.statCards).forEach(card => card.mount());
        Object.values(this.charts).forEach(chart => chart.mount());
    }

    /**
     * 绑定事件
     */
    bindEvents() {
        // 标签页切换
        this.container.querySelectorAll('.tab-button').forEach(button => {
            button.addEventListener('click', (e) => {
                const tabId = e.currentTarget.dataset.tab;
                this.switchTab(tabId);
            });
        });

        // 筛选器变化
        if (this.filterPanel) {
            this.filterPanel.on('filter', (filters) => {
                this.handleFilter(filters);
            });
        }
    }

    /**
     * 加载分析任务
     */
    async loadTasks() {
        try {
            const response = await this.apiClient.get('/api/analysis-tasks', {
                params: {
                    status: 'completed',
                    limit: 100
                }
            });

            if (response.success && response.data) {
                const tasks = response.data.tasks || response.data.items || response.data || [];
                const taskOptions = tasks.map(task => ({
                    value: task.id,
                    label: task.name || `任务 ${task.id}`
                }));

                // 更新筛选面板的选项
                this.filterPanel.updateFilterOptions('task_id', [
                    { value: '', label: '全部任务' },
                    ...taskOptions
                ]);
            }
        } catch (error) {
            console.error('加载任务失败:', error);
            this.showNotification('加载任务失败', 'error');
        }
    }

    /**
     * 设置默认日期
     */
    setDefaultDates() {
        const today = new Date();
        const thirtyDaysAgo = new Date(today.getTime() - 30 * 24 * 60 * 60 * 1000);

        const endDate = today.toISOString().split('T')[0];
        const startDate = thirtyDaysAgo.toISOString().split('T')[0];

        this.filterPanel.setFilterValue('start_date', startDate);
        this.filterPanel.setFilterValue('end_date', endDate);
    }

    /**
     * 处理筛选
     */
    async handleFilter(filters) {
        this.state.filters = { ...this.state.filters, ...filters };
        await this.loadAnalysis();
    }

    /**
     * 加载分析数据
     */
    async loadAnalysis() {
        this.setLoading(true);

        try {
            const response = await this.apiClient.post('/api/duplicate-analysis/analyze', this.state.filters);

            if (response.success) {
                this.state.data = response.data;
                this.updateDashboard(response.data);
                this.updateAllCharts(response.data);
            } else {
                this.showNotification('分析失败: ' + response.message, 'error');
            }
        } catch (error) {
            console.error('分析失败:', error);
            this.showNotification('分析失败: ' + error.message, 'error');
        } finally {
            this.setLoading(false);
        }
    }

    /**
     * 更新仪表板
     */
    updateDashboard(data) {
        if (!data || !data.analysis_metadata) return;

        const metadata = data.analysis_metadata;
        const similarityDist = data.similarity_distribution || {};

        // 更新统计卡片
        this.statCards.totalRecords.updateValue(metadata.total_records.toLocaleString());
        this.statCards.avgSimilarity.updateValue(similarityDist.average_similarity?.toFixed(3) || '-');
        this.statCards.duplicateRate.updateValue(
            similarityDist.duplicate_rate ? (similarityDist.duplicate_rate * 100).toFixed(1) + '%' : '-'
        );
        this.statCards.potentialDuplicates.updateValue(
            similarityDist.potential_duplicates?.toLocaleString() || '-'
        );
    }

    /**
     * 更新所有图表
     */
    updateAllCharts(data) {
        this.updateSimilarityDistributionChart(data.similarity_distribution);
        this.updateClusterAnalysisChart(data.cluster_analysis);
        this.updatePopularDuplicatesChart(data.popular_duplicates);
        this.updateDuplicateTrendsChart(data.duplicate_trends);
        this.updateDuplicateDetails(data.duplicate_details);
        this.updateSimilarityStats(data.similarity_distribution);
        this.updateClusterStats(data.cluster_analysis);
        this.updateClusterVisualization(data.cluster_analysis);
        this.updatePopularRanking(data.popular_duplicates);
    }

    /**
     * 更新相似度分布图表
     */
    updateSimilarityDistributionChart(data) {
        if (!data || !data.distribution_ranges) return;

        const ranges = Object.keys(data.distribution_ranges);
        const counts = Object.values(data.distribution_ranges);

        const option = {
            title: {
                text: '相似度分布',
                left: 'center',
                textStyle: {
                    fontSize: 16,
                    fontWeight: 'bold'
                }
            },
            tooltip: {
                trigger: 'axis',
                formatter: '{b}: {c} 条记录'
            },
            xAxis: {
                type: 'category',
                data: ranges,
                axisLabel: {
                    rotate: 45,
                    fontSize: 12
                }
            },
            yAxis: {
                type: 'value',
                name: '记录数量',
                nameTextStyle: {
                    fontSize: 12
                }
            },
            series: [{
                data: counts,
                type: 'bar',
                itemStyle: {
                    color: function(params) {
                        const value = parseFloat(params.name.split('-')[0]);
                        if (value >= 0.8) return '#ef4444';
                        if (value >= 0.6) return '#f59e0b';
                        return '#10b981';
                    }
                },
                emphasis: {
                    itemStyle: {
                        shadowBlur: 10,
                        shadowOffsetX: 0,
                        shadowColor: 'rgba(0, 0, 0, 0.5)'
                    }
                }
            }],
            grid: {
                bottom: '15%',
                left: '10%',
                right: '10%'
            }
        };

        this.charts.similarityDistribution.setOption(option);
    }

    /**
     * 更新簇分析图表
     */
    updateClusterAnalysisChart(data) {
        if (!data || !data.clusters) return;

        const clusters = data.clusters;
        const sizes = clusters.map(cluster => cluster.size);
        const labels = clusters.map((cluster, index) => `簇${index + 1}`);

        const option = {
            title: {
                text: '重复簇大小分布',
                left: 'center',
                textStyle: {
                    fontSize: 16,
                    fontWeight: 'bold'
                }
            },
            tooltip: {
                trigger: 'axis',
                formatter: '{b}: {c} 条记录'
            },
            xAxis: {
                type: 'category',
                data: labels,
                axisLabel: {
                    fontSize: 12
                }
            },
            yAxis: {
                type: 'value',
                name: '簇大小',
                nameTextStyle: {
                    fontSize: 12
                }
            },
            series: [{
                data: sizes,
                type: 'bar',
                itemStyle: {
                    color: '#ef4444'
                },
                emphasis: {
                    itemStyle: {
                        shadowBlur: 10,
                        shadowOffsetX: 0,
                        shadowColor: 'rgba(0, 0, 0, 0.5)'
                    }
                }
            }],
            grid: {
                bottom: '10%',
                left: '10%',
                right: '10%'
            }
        };

        this.charts.clusterAnalysis.setOption(option);
    }

    /**
     * 更新热门重复图表
     */
    updatePopularDuplicatesChart(data) {
        if (!data || !Array.isArray(data)) return;

        const contents = data.map(item => item.content.substring(0, 20) + '...');
        const frequencies = data.map(item => item.frequency);

        const option = {
            title: {
                text: '热门重复内容',
                left: 'center',
                textStyle: {
                    fontSize: 16,
                    fontWeight: 'bold'
                }
            },
            tooltip: {
                trigger: 'axis',
                formatter: '{b}: {c} 次'
            },
            xAxis: {
                type: 'category',
                data: contents,
                axisLabel: {
                    rotate: 45,
                    fontSize: 10,
                    interval: 0
                }
            },
            yAxis: {
                type: 'value',
                name: '重复次数',
                nameTextStyle: {
                    fontSize: 12
                }
            },
            series: [{
                data: frequencies,
                type: 'bar',
                itemStyle: {
                    color: '#f59e0b'
                },
                emphasis: {
                    itemStyle: {
                        shadowBlur: 10,
                        shadowOffsetX: 0,
                        shadowColor: 'rgba(0, 0, 0, 0.5)'
                    }
                }
            }],
            grid: {
                bottom: '25%',
                left: '10%',
                right: '10%'
            }
        };

        this.charts.popularDuplicates.setOption(option);
    }

    /**
     * 更新重复趋势图表
     */
    updateDuplicateTrendsChart(data) {
        if (!data || !Array.isArray(data)) return;

        const dates = data.map(item => item.date);
        const counts = data.map(item => item.count);
        const similarityScores = data.map(item => item.avg_similarity);

        const option = {
            title: {
                text: '重复趋势',
                left: 'center',
                textStyle: {
                    fontSize: 16,
                    fontWeight: 'bold'
                }
            },
            tooltip: {
                trigger: 'axis',
                formatter: function(params) {
                    let result = params[0].name + '<br/>';
                    params.forEach(param => {
                        result += `${param.marker}${param.seriesName}: ${param.value}<br/>`;
                    });
                    return result;
                }
            },
            legend: {
                data: ['重复数量', '平均相似度'],
                top: 30
            },
            xAxis: {
                type: 'category',
                data: dates,
                axisLabel: {
                    rotate: 45,
                    fontSize: 10
                }
            },
            yAxis: [
                {
                    type: 'value',
                    name: '数量',
                    position: 'left',
                    nameTextStyle: {
                        fontSize: 12
                    }
                },
                {
                    type: 'value',
                    name: '相似度',
                    min: 0,
                    max: 1,
                    position: 'right',
                    nameTextStyle: {
                        fontSize: 12
                    }
                }
            ],
            series: [
                {
                    name: '重复数量',
                    type: 'bar',
                    data: counts,
                    itemStyle: {
                        color: '#ef4444'
                    }
                },
                {
                    name: '平均相似度',
                    type: 'line',
                    yAxisIndex: 1,
                    data: similarityScores,
                    itemStyle: {
                        color: '#f59e0b'
                    },
                    lineStyle: {
                        width: 2
                    }
                }
            ],
            grid: {
                bottom: '20%',
                left: '10%',
                right: '10%'
            }
        };

        this.charts.duplicateTrends.setOption(option);
    }

    /**
     * 更新重复详情
     */
    updateDuplicateDetails(data) {
        const container = document.getElementById(`${this.id}_duplicateDetails`);
        if (!container) return;

        if (!data || !Array.isArray(data) || data.length === 0) {
            container.innerHTML = '<div class="text-center text-gray-500 py-8">暂无重复详情</div>';
            return;
        }

        const html = data.map(item => {
            const similarityClass = item.similarity_score >= 0.8 ? 'high' :
                                   item.similarity_score >= 0.6 ? 'medium' : 'low';
            const similarityColor = item.similarity_score >= 0.8 ? 'red' :
                                   item.similarity_score >= 0.6 ? 'yellow' : 'green';

            return `
                <div class="border border-gray-200 rounded-lg p-4 hover:shadow-md transition-shadow">
                    <div class="flex justify-between items-start mb-3">
                        <span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-${similarityColor}-100 text-${similarityColor}-800">
                            相似度: ${(item.similarity_score * 100).toFixed(1)}%
                        </span>
                        <span class="text-sm text-gray-500">${item.created_at || '未知时间'}</span>
                    </div>

                    <div class="mb-3">
                        <h4 class="font-semibold text-gray-800 mb-1">主要内容:</h4>
                        <p class="text-gray-600 text-sm">${item.content || '无内容'}</p>
                    </div>

                    <div class="mb-3">
                        <h4 class="font-semibold text-gray-800 mb-1">相似内容:</h4>
                        <p class="text-gray-600 text-sm">${item.similar_content || '无相似内容'}</p>
                    </div>

                    <div class="flex justify-between items-center text-sm text-gray-500">
                        <span>簇ID: ${item.cluster_id || '无'}</span>
                        <span>匹配数: ${item.match_count || 0}</span>
                    </div>
                </div>
            `;
        }).join('');

        container.innerHTML = html;
    }

    /**
     * 更新相似度统计
     */
    updateSimilarityStats(data) {
        const container = document.getElementById(`${this.id}_similarityStats`);
        if (!container) return;

        if (!data) {
            container.innerHTML = '<div class="text-center text-gray-500 py-4">暂无统计数据</div>';
            return;
        }

        const html = `
            <div class="flex justify-between items-center py-2 border-b border-gray-100">
                <span class="text-gray-600">平均相似度</span>
                <span class="font-semibold text-red-600">${data.average_similarity?.toFixed(3) || '-'}</span>
            </div>
            <div class="flex justify-between items-center py-2 border-b border-gray-100">
                <span class="text-gray-600">最高相似度</span>
                <span class="font-semibold text-red-600">${data.max_similarity?.toFixed(3) || '-'}</span>
            </div>
            <div class="flex justify-between items-center py-2 border-b border-gray-100">
                <span class="text-gray-600">最低相似度</span>
                <span class="font-semibold text-green-600">${data.min_similarity?.toFixed(3) || '-'}</span>
            </div>
            <div class="flex justify-between items-center py-2 border-b border-gray-100">
                <span class="text-gray-600">高相似度数量</span>
                <span class="font-semibold text-red-600">${data.high_similarity_count || 0}</span>
            </div>
            <div class="flex justify-between items-center py-2">
                <span class="text-gray-600">重复率</span>
                <span class="font-semibold text-red-600">${data.duplicate_rate ? (data.duplicate_rate * 100).toFixed(1) + '%' : '-'}</span>
            </div>
        `;

        container.innerHTML = html;
    }

    /**
     * 更新簇统计
     */
    updateClusterStats(data) {
        const container = document.getElementById(`${this.id}_clusterStats`);
        if (!container) return;

        if (!data) {
            container.innerHTML = '<div class="text-center text-gray-500 py-4">暂无簇统计数据</div>';
            return;
        }

        const html = `
            <div class="flex justify-between items-center py-2 border-b border-gray-100">
                <span class="text-gray-600">总簇数</span>
                <span class="font-semibold text-gray-800">${data.total_clusters || 0}</span>
            </div>
            <div class="flex justify-between items-center py-2 border-b border-gray-100">
                <span class="text-gray-600">最大簇大小</span>
                <span class="font-semibold text-gray-800">${data.max_cluster_size || 0}</span>
            </div>
            <div class="flex justify-between items-center py-2 border-b border-gray-100">
                <span class="text-gray-600">平均簇大小</span>
                <span class="font-semibold text-gray-800">${data.average_cluster_size?.toFixed(1) || '-'}</span>
            </div>
            <div class="flex justify-between items-center py-2">
                <span class="text-gray-600">有效簇数</span>
                <span class="font-semibold text-gray-800">${data.valid_clusters || 0}</span>
            </div>
        `;

        container.innerHTML = html;
    }

    /**
     * 更新簇可视化
     */
    updateClusterVisualization(data) {
        const container = document.getElementById(`${this.id}_clusterVisualization`);
        if (!container) return;

        if (!data || !data.clusters) {
            container.innerHTML = '<div class="text-center text-gray-500 py-8">暂无簇可视化数据</div>';
            return;
        }

        const html = data.clusters.slice(0, 5).map((cluster, clusterIndex) => `
            <div class="bg-gray-50 rounded-lg p-4 border border-gray-200">
                <div class="flex items-center justify-between mb-3">
                    <h4 class="font-semibold text-gray-800">簇 ${clusterIndex + 1}</h4>
                    <span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-blue-100 text-blue-800">
                        大小: ${cluster.size}
                    </span>
                </div>
                <div class="flex flex-wrap gap-2">
                    ${cluster.items.slice(0, 8).map((item, itemIndex) => {
                        const nodeClass = itemIndex === 0 ? 'bg-red-500 text-white' : 'bg-yellow-500 text-white';
                        return `<span class="inline-flex items-center px-3 py-1 rounded-full text-xs font-medium ${nodeClass}">
                            ${item.content.substring(0, 10)}...
                        </span>`;
                    }).join('')}
                    ${cluster.items.length > 8 ? `
                        <span class="inline-flex items-center px-3 py-1 rounded-full text-xs font-medium bg-gray-500 text-white">
                            ...还有${cluster.items.length - 8}项
                        </span>
                    ` : ''}
                </div>
            </div>
        `).join('');

        container.innerHTML = html;
    }

    /**
     * 更新热门排行
     */
    updatePopularRanking(data) {
        const container = document.getElementById(`${this.id}_popularRanking`);
        if (!container) return;

        if (!data || !Array.isArray(data)) {
            container.innerHTML = '<div class="text-center text-gray-500 py-4">暂无排行数据</div>';
            return;
        }

        const html = data.slice(0, 10).map((item, index) => {
            const similarityColor = item.avg_similarity >= 0.8 ? 'red' :
                                   item.avg_similarity >= 0.6 ? 'yellow' : 'green';

            return `
                <div class="flex justify-between items-center py-3 border-b border-gray-100 last:border-b-0">
                    <div class="flex-1">
                        <div class="flex items-center space-x-2">
                            <span class="flex-shrink-0 w-6 h-6 bg-blue-100 text-blue-800 text-xs font-medium rounded-full flex items-center justify-center">
                                ${index + 1}
                            </span>
                            <span class="text-sm font-medium text-gray-800 truncate">
                                ${item.content.substring(0, 15)}...
                            </span>
                        </div>
                        <div class="ml-8 mt-1">
                            <span class="text-xs text-gray-500">
                                平均相似度: <span class="font-medium text-${similarityColor}-600">${(item.avg_similarity * 100).toFixed(1)}%</span>
                            </span>
                        </div>
                    </div>
                    <div class="flex-shrink-0 ml-4">
                        <span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-gray-100 text-gray-800">
                            ${item.frequency}
                        </span>
                    </div>
                </div>
            `;
        }).join('');

        container.innerHTML = html;
    }

    /**
     * 切换标签页
     */
    switchTab(tabId) {
        // 更新状态
        this.state.activeTab = tabId;

        // 更新标签按钮样式
        this.container.querySelectorAll('.tab-button').forEach(button => {
            const buttonTabId = button.dataset.tab;
            if (buttonTabId === tabId) {
                button.className = 'tab-button py-4 px-1 border-b-2 font-medium text-sm focus:outline-none transition-colors border-blue-500 text-blue-600';
            } else {
                button.className = 'tab-button py-4 px-1 border-b-2 font-medium text-sm focus:outline-none transition-colors border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300';
            }
        });

        // 更新标签内容显示
        this.container.querySelectorAll('.tab-pane').forEach(pane => {
            pane.classList.remove('active');
            pane.style.display = 'none';
        });

        const activePane = this.container.querySelector(`#${tabId}-pane`);
        if (activePane) {
            activePane.classList.add('active');
            activePane.style.display = 'block';

            // 触发图表重绘
            setTimeout(() => {
                this.trigger(`tab:switched:${tabId}`);
                this.resizeCharts();
            }, 100);
        }
    }

    /**
     * 调整图表大小
     */
    resizeCharts() {
        Object.values(this.charts).forEach(chart => {
            if (chart && chart.resize) {
                chart.resize();
            }
        });
    }

    /**
     * 设置加载状态
     */
    setLoading(loading) {
        this.state.loading = loading;
        const overlay = document.getElementById(`${this.id}_loadingOverlay`);
        if (overlay) {
            overlay.classList.toggle('hidden', !loading);
        }

        // 更新筛选面板状态
        if (this.filterPanel) {
            this.filterPanel.setLoading(loading);
        }
    }

    /**
     * 显示通知
     */
    showNotification(message, type = 'info') {
        this.trigger('notification:show', {
            message,
            type,
            duration: 3000
        });
    }

    /**
     * 销毁组件
     */
    destroy() {
        // 销毁子组件
        if (this.filterPanel) {
            this.filterPanel.destroy();
        }

        Object.values(this.statCards).forEach(card => {
            if (card) card.destroy();
        });

        Object.values(this.charts).forEach(chart => {
            if (chart) chart.destroy();
        });

        // 清除事件监听
        this.removeAllEventListeners();

        // 清除DOM
        if (this.container && this.container.parentNode) {
            this.container.parentNode.removeChild(this.container);
        }
    }
}

// 导出组件
window.DuplicateAnalysis = DuplicateAnalysis;